home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / MCASM.RAR / MC_ASM.EXE / WROX_ASM / CH12 / GRAPH / GRAPH.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-16  |  13.6 KB  |  650 lines

  1. // This is the code graphic system's kernel
  2. // Written by Kiselev J., CZ 1994.
  3.  
  4. #pragma -ml
  5.  
  6. #include <conio.h>
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <mem.h>
  10. #include <dos.h>
  11.  
  12. #include "graph.h"
  13.  
  14. //borland's default patterns
  15. const char CZsign[] = "^Z Graphics Library. Control Zed Ltd. (c) 1993-94";
  16. BYTE patterns[12][8] = {{0,0,0,0,0,0,0,0},
  17.             {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
  18.             {0xff,0xff,0,0,0xff,0xff,0,0},
  19.             {1,2,4,8,0x10,0x20,0x40,0x80},
  20.             {0xe0,0xc1,0x83,7,0xe,0x1c,0x38,0x70},
  21.             {0xf0,0x78,0x3c,0x1e,0xf,0x87,0xc3,0xe1},
  22.             {0xa5,0xd2,0x69,0xb4,0x5a,0x2d,0x96,0x4b},
  23.             {0xff,0x88,0x88,0x88,0xff,0x88,0x88,0x88},
  24.             {0x81,0x42,0x24,0x18,0x18,0x24,0x42,0x81},
  25.             {0xcc,0x33,0xcc,0x33,0xcc,0x33,0xcc,0x33},
  26.             {0x80,0,8,0,0x80,0,8,0},
  27.             {0x88,0,0x22,0,0x88,0,0x22,0}};
  28.  
  29. //borlands's line styles
  30. WORD solidline    = 0xffff;
  31. WORD dottedline    = 0xcccc;
  32. WORD centerline    = 0xfc78;
  33. WORD dashedline    = 0xf8f8;
  34.  
  35. typedef char str[13];
  36. const str arraymodenames[11] = {"640x350 16",
  37.             "640x480 16",
  38.             "320x200 256",
  39.             "800x600 16",
  40.             "640x400 256",
  41.             "640x480 256",
  42.             "800x600 256",
  43.             "1024x768 16",
  44.             "1024x768 256",
  45.             "1280x1024 16",
  46.             "1280x1024 256"};
  47. typedef struct
  48.     {
  49.     int width;
  50.     int height;
  51.     WORD bytesperline;
  52.     BYTE BIOSmode;
  53.     WORD VESAmode;
  54.     BYTE modenum;
  55.     BYTE VESAgrwinshift;
  56.     } modetype;
  57.  
  58. modetype arraymodeset[11] = {{640,350,80,0x10,0,0},
  59.                  {640,480,80,0x12,0,1},
  60.                  {320,200,320,0x13,0,2},
  61.                  {800,600,100,0,0x102,3},
  62.                  {640,400,640,0,0x100,4},
  63.                  {640,480,640,0,0x101,5},
  64.                  {800,600,800,0,0x103,6},
  65.                  {1024,768,128,0,0x104,7},
  66.                  {1024,768,1024,0,0x105,8},
  67.                  {1280,1024,160,0,0x106,14},
  68.                  {1280,1024,1280,0,0x107,15}};
  69. const NormalPut = 0;
  70. const AndPut    = 1 << 3;
  71. const OrPut     = 2 << 3;
  72. const XORPut    = 3 << 3;
  73.  
  74. BOOL drawpoly_in_fillpoly = TRUE;
  75. modelisttype modelist;
  76. modetype activemode;
  77.  
  78. BYTE mono,oldmode;
  79. int currx,curry;
  80. linesettingstype linetype;
  81. BYTE* userpatternptr;
  82. BOOL graph_is_ready = FALSE;
  83.  
  84. const char VESAcall    = 0x4f;
  85. const char VESAsign[4]    = "VESA";
  86.  
  87. //VESA Control function
  88. const char getVESAinfo    = 0;
  89. const char getmodeinfo    = 1;
  90. const char setVESAmode    = 2;
  91. const char getVESAmode    = 3;
  92. const char SVGAstate    = 4;
  93. const char swichbank    = 5;
  94.  
  95. enum proc_offsets {
  96.     indexputpixel,
  97.     indexdrawline,
  98.     indexbar,
  99.     indexputimage,
  100.     indexgetimage,
  101.     indeximagesize,
  102.     indexputrow,
  103.     indexdrawpolygon,
  104.     indexchangeput,
  105.     indexgetpixel
  106. };
  107.  
  108. extern "C" WORD testadapter(void);
  109. extern "C" void normalline(int x1,int y1,int x2,int y2);
  110. extern "C" BYTE clippixel(int x,int y);
  111.  
  112. extern viewporttype viewport;
  113. extern viewporttype viewport32767;
  114. extern WORD videoselector;
  115. extern WORD bytesperline;
  116. extern WORD linepattern;
  117. extern BYTE* fillpatternptr;
  118. extern patterntype;
  119. extern trflag;
  120. extern BYTE drawcolor;
  121. extern BYTE fillcolor;
  122. extern BYTE backcolor;
  123. extern BYTE writemode;
  124. extern int *ArrayScanLinesPtr;
  125. extern WORD sizeonerow;
  126. extern void *far callVESAswbnkptr;
  127. extern BYTE grshift;
  128.  
  129. extern proctable16;
  130. extern proctable256;
  131. extern proctables256;
  132.  
  133. void *far proctable = &proctable16;
  134.  
  135. void (*line)(int x1,int y1,int x2,int y2);
  136.  
  137. int SVGAsearch(void)
  138. {
  139. BYTE mcount,i;
  140. WORD mode,j;
  141. struct {
  142.     char VESAsignature[4];
  143.     WORD VESAversion;
  144.     char far *OEMstringptr;
  145.     long capabilities;
  146.     int far *videomodeptr;
  147.     BYTE reserved[238];
  148.     } VESAinfo;
  149. struct {
  150.     WORD modeattributes;
  151.     BYTE winAattributes;
  152.     BYTE winBattributes;
  153.     WORD wingranularity;
  154.     WORD winsize;
  155.     WORD winAsegment;
  156.     WORD winBsegment;
  157.     void *winfuncptr;
  158.     WORD bytesperscanline;
  159. // end of obligatory structure
  160.     WORD Xresolution;
  161.     WORD Yresolution;
  162.     BYTE Xcharcellsize;
  163.     BYTE Ycharcellsize;
  164.     BYTE numberofplanes;
  165.     BYTE bitsperpixel;
  166.     BYTE numberofbanks;
  167.     BYTE memorymodel;
  168.     BYTE banksize;
  169.     BYTE reserved[227];
  170.     } modeinfo;
  171.  
  172. asm    {
  173.         mov ax,ss
  174.         mov es,ax
  175.         lea di,VESAinfo
  176.         mov ah,VESAcall
  177.         mov al,getVESAinfo
  178.         int 10h
  179.     }
  180. if (_AX != 0x4F) return(-1);
  181. if (_fmemcmp(MK_FP(_ES,_DI),VESAsign,4) != 0) return(-1);
  182. while(*VESAinfo.videomodeptr != -1)
  183. {
  184. asm {
  185.         les di,dword ptr VESAinfo.videomodeptr
  186.         mov cx,es:[di]
  187.         mov mode,cx
  188.         mov ax,ss
  189.         mov es,ax
  190.         lea di,modeinfo
  191.         mov ah,VESAcall
  192.         mov al,getmodeinfo
  193.         int 10h
  194.         add word ptr VESAinfo.videomodeptr[0],2    //offset next mode
  195.   }
  196.   if (_AX != 0x4f) continue;
  197.   if ((modeinfo.modeattributes & 0x10) == 0) continue; // It is a graphics mode
  198.   for(j=1;j<=modecounter;j++)
  199.   {
  200.     if (arraymodeset[j].VESAmode == mode)
  201.     {
  202.       modelist.modes[modelist.numberofmodes].mode = j;
  203.       memcpy(modelist.modes[modelist.numberofmodes].name,
  204.         arraymodenames[j],sizeof(arraymodenames[0]));
  205.       if (modeinfo.winfuncptr != NULL) callVESAswbnkptr = modeinfo.winfuncptr;
  206.       if (modeinfo.bytesperscanline != arraymodeset[j].bytesperline)
  207.         arraymodeset[j].bytesperline = modeinfo.bytesperscanline;
  208.       switch (modeinfo.wingranularity)
  209.       {
  210.     case 64 : arraymodeset[j].VESAgrwinshift=0; break;
  211.     case 32 : arraymodeset[j].VESAgrwinshift=1; break;
  212.     case 16 : arraymodeset[j].VESAgrwinshift=2; break;
  213.     case  8 : arraymodeset[j].VESAgrwinshift=3; break;
  214.     case  4 : arraymodeset[j].VESAgrwinshift=4; break;
  215.     case  1 : arraymodeset[j].VESAgrwinshift=5; break;
  216.     default : printf("Internal error.\a"); //oops
  217.       }
  218.       modelist.numberofmodes++;
  219.       break;
  220.   }
  221. }
  222. }
  223. return(0);
  224. }
  225.  
  226. int graphinit(void)
  227. {
  228. WORD device;
  229.     asm    mov ah,0xf
  230.     asm    int 0x10
  231.     asm    mov oldmode,al
  232. device = testadapter();
  233. switch (device >> 8)
  234.     {
  235.     case -1 : return(-1);
  236.     case 2  : mono = TRUE;
  237.     }
  238. switch (device & 0x00ff)
  239.     {
  240.     case -1 : return(-1);
  241.     case 3  :
  242.     {
  243.     // standart VGA modes : (640x350x16) 640x480x16 or 320x200x256
  244.     activemode = arraymodeset[VGA16];
  245.     modelist.modes[0].mode = EGA16;
  246.     memcpy(modelist.modes[0].name,
  247.         arraymodenames[EGA16],sizeof(arraymodenames[0]));
  248.     modelist.modes[1].mode = VGA16;
  249.     memcpy(modelist.modes[1].name,
  250.         arraymodenames[VGA16],sizeof(arraymodenames[0]));
  251.     modelist.modes[2].mode = VGA256;
  252.     memcpy(modelist.modes[2].name,
  253.         arraymodenames[VGA256],sizeof(arraymodenames[0]));
  254.     modelist.numberofmodes += 3;
  255.     // check VESA BIOS extention
  256.     SVGAsearch();
  257.     }; break;
  258.     case 2 :
  259.     {
  260.     activemode = arraymodeset[EGA16];
  261.     modelist.modes[0].mode = EGA16;
  262.     memcpy(modelist.modes[0].name,
  263.         arraymodenames[EGA16],sizeof(arraymodenames[0]));
  264.     }
  265.     }
  266. _AH = 0;
  267. _AL = activemode.BIOSmode;
  268. geninterrupt(0x10);
  269. // default settings
  270. setviewport(0,0,activemode.width-1,activemode.height-1);
  271. line = normalline;
  272. drawcolor = fillcolor = WHITE;
  273. backcolor = BLACK;
  274. bytesperline = activemode.bytesperline;
  275. linepattern = 0xffff;
  276. if ((ArrayScanLinesPtr = (int *) malloc(activemode.height*sizeonerow)) == NULL)
  277. {
  278.    printf("Not enough memory to allocate buffer\n"); // for fillpoly routine
  279.    return(-1);  // terminate program if out of memory
  280. }
  281. graph_is_ready = TRUE;
  282. return(0);
  283. }
  284.  
  285. int switchmode(int mode)
  286. {
  287. int i;
  288. if (!graph_is_ready) return(-1);
  289. if (mode != activemode.modenum)
  290.     {
  291.     for(i=0;i<=modelist.numberofmodes;i++)
  292.         if (mode == modelist.modes[i].mode)
  293.         {
  294.             if (arraymodeset[i].BIOSmode != 0)
  295.             {
  296.                 activemode = arraymodeset[mode];
  297.                 _AH = 0;
  298.                 _AL = activemode.BIOSmode;
  299.                 geninterrupt(0x10);
  300.             }
  301.             else
  302.             {
  303.                 activemode = arraymodeset[mode];
  304.                 _AH = VESAcall;
  305.                 _AL = setVESAmode;
  306.                 _BX = activemode.VESAmode;
  307.                 geninterrupt(0x10);
  308.             }
  309.         i = -1;
  310.         break;
  311.         }
  312.     }
  313. if (i != -1) return(-1);
  314. else
  315. {
  316. free(ArrayScanLinesPtr);
  317. if ((ArrayScanLinesPtr = (int *) malloc(activemode.height*sizeonerow)) == NULL)
  318. {
  319.    printf("Not enough memory to allocate buffer\n");
  320.    return(-1);  // terminate program if out of memory
  321. }
  322. // default settings
  323. setviewport(0,0,activemode.width-1,activemode.height-1);
  324. line = normalline;
  325. drawcolor = 15;
  326. fillcolor = 15;
  327. backcolor = 0;
  328. bytesperline = activemode.bytesperline;
  329. linepattern = 0xffff;
  330. switch (mode) {
  331.     case EGA16 : proctable = &proctable16; break;
  332.     case VGA16 : proctable = &proctable16; break;
  333.     case VGA256 : proctable = &proctable256; break;
  334.     case SVGA640x400x256 :
  335.     case SVGA640x480x256 :
  336.     case SVGA800x600x256 :
  337.     case SVGA1024x768x256 :
  338.     case SVGA1280x1024x256 : proctable = &proctables256;
  339. }
  340. grshift = arraymodeset[mode].VESAgrwinshift;
  341. return(0);
  342. }
  343. }
  344.  
  345. void setviewport(int x1,int y1,int x2,int y2)
  346. {
  347. // add 32768 for fast clip lines (integer to word)
  348. viewport.left = x1;
  349. viewport32767.left = x1 + 32768;
  350. viewport.top = y1;
  351. viewport32767.top = y1 + 32768;
  352. viewport.right = x2;
  353. viewport32767.right = x2 + 32768;
  354. viewport.bottom = y2;
  355. viewport32767.bottom = y2 + 32768;
  356. }
  357.  
  358. void midlleline(int x1,int y1,int x2,int y2)
  359. {
  360. int i;
  361. if (abs(x2-x1) > abs(y2-y1)) //lo slope
  362. for(i=0;i<=linetype.width-1;i++) normalline(x1,y1+i,x2,y2+i);
  363. else //hi slope
  364. for(i=0;i<=linetype.width-1;i++) normalline(x1+i,y1,x2+i,y2);
  365. }
  366.  
  367. void putpixel(int x,int y,BYTE color)
  368. {
  369. if (clippixel(x,y) == 0)
  370. asm {
  371.         push ds
  372.         mov ax,SEG proctable
  373.         mov ds,ax
  374.         lea si,proctable
  375.         les si,[si]
  376.         mov al,color
  377.         push ax
  378.         push cx
  379.         push dx
  380.         call dword ptr es:[si+indexputpixel*4]
  381.         add sp,6
  382.         pop ds
  383. }
  384. }
  385.  
  386. BYTE getpixel(int x,int y)
  387. {
  388. asm {
  389.         push ds
  390.         mov ax,SEG proctable
  391.         mov ds,ax
  392.         lea si,proctable
  393.         les si,[si]
  394.         push y
  395.         push x
  396.         call dword ptr es:[si+indexgetpixel*4]
  397.         add sp,4
  398.         pop ds
  399. }
  400. }
  401.  
  402. void moveto(int x,int y)
  403. {
  404.   currx = x;
  405.   curry = y;
  406. }
  407.  
  408. void moverel(int dx,int dy)
  409. {
  410.   currx+=dx;
  411.   curry+=dy;
  412. }
  413.  
  414. void rectangle(int x1,int y1,int x2,int y2)
  415. {
  416.   line(x1,y1,x2,y1);
  417.   line(x2,y1,x2,y2);
  418.   line(x2,y2,x1,y2);
  419.   line(x1,y1,x1,y2);
  420. }
  421.  
  422. void lineto(int x,int y)
  423. {
  424.   line(currx,curry,x,y);
  425.   currx = x;
  426.   curry = y;
  427. }
  428.  
  429. void linerel(int dx,int dy)
  430. {
  431.   line(currx,curry,currx+dx,curry+dy);
  432.   currx+=dx;
  433.   curry+=dy;
  434. }
  435.  
  436. int getmaxx(void) {return(activemode.width-1);}
  437.  
  438. int getmaxy(void) {return(activemode.height-1);}
  439.  
  440. void setwritemode(BYTE wrmode)
  441. {
  442. if ((wrmode <= OR_PUT) && (wrmode != writemode))
  443. {
  444.     writemode = wrmode;
  445. asm {
  446.         push ds
  447.         mov ax,SEG proctable
  448.         mov ds,ax
  449.         lea si,proctable
  450.         les si,[si]
  451.         mov ah,wrmode
  452.         call dword ptr es:[si+indexchangeput*4]
  453.         pop ds
  454.     }
  455. }
  456. }
  457.  
  458. void bar(int x,int y,int x1,int y1)
  459. {
  460. asm {
  461.         push ds
  462.         mov ax,SEG proctable
  463.         mov ds,ax
  464.         lea si,proctable
  465.         les si,[si]
  466.         push y1
  467.         push x1
  468.         push y
  469.         push x
  470.         call dword ptr es:[si+indexbar*4]
  471.         add sp,8
  472.         pop ds
  473. }
  474. }
  475.  
  476. void putrow(rowptr row,int x,int y,int xcount)
  477. {
  478. asm {
  479.         push ds
  480.         mov ax,SEG proctable
  481.         mov ds,ax
  482.         lea si,proctable
  483.         les si,[si]
  484.         push xcount
  485.         push y
  486.         push x
  487.         mov ax,word ptr row[2]
  488.         push ax
  489.         mov ax,word ptr row
  490.         push ax
  491.         call dword ptr es:[si+indexputrow*4]
  492.         add sp,10
  493.         pop ds
  494. }
  495. }
  496.  
  497. void setlinestyle(WORD linestyle,WORD pattern,BYTE wline)
  498. {
  499. linetype.linestyle = linestyle;
  500. linetype.pattern = pattern;
  501. linetype.width = wline;
  502. switch (linestyle) {
  503. case SOLID_LINE : linepattern = solidline; break;
  504. case DOTTED_LINE : linepattern = dottedline; break;
  505. case CENTER_LINE : linepattern = centerline; break;
  506. case DASHED_LINE : linepattern = dashedline; break;
  507. default : USERBIT_LINE : linepattern = pattern;
  508. }
  509. switch (wline) {
  510. case NORM_WIDTH : line = normalline; break;
  511. case DOUBLE_WIDTH : line = midlleline; break;
  512. case THICK_WIDTH : line = midlleline; break;
  513. default : line = normalline;
  514. }
  515. }
  516.  
  517. void setfillstyle(BYTE pattern,BYTE color)
  518. {
  519. if (pattern == USER_FILL) fillpatternptr = userpatternptr;
  520.     else fillpatternptr = (BYTE*)MK_FP(FP_SEG(patterns[pattern]),
  521.                         FP_OFF(patterns[pattern]));
  522. fillcolor = color;
  523. patterntype = pattern;
  524. }
  525.  
  526. void setfillpattern(BYTE* pattern) { userpatternptr = pattern;}
  527.  
  528. void setcolor(BYTE color) {drawcolor = color;}
  529. BYTE getcolor(void) {return(drawcolor);}
  530. void setbkcolor(BYTE color) {backcolor = color;}
  531.  
  532. void getimage(int x1,int y1,int x2,int y2,void* buffer)
  533. {
  534. asm {
  535.         push ds
  536.         mov ax,SEG proctable
  537.         mov ds,ax
  538.         lea si,proctable
  539.         les si,[si]
  540.         mov ax,word ptr buffer[2]
  541.         push ax
  542.         mov ax,word ptr buffer
  543.         push ax
  544.         push y2
  545.         push x2
  546.         push y1
  547.         push x1
  548.         call dword ptr es:[si+indexgetimage*4]
  549.         add sp,12
  550.         pop ds
  551. }
  552. }
  553.  
  554. void putimage(int xo,int yo,void* buffer)
  555. {
  556. asm {
  557.         push ds
  558.         mov ax,SEG proctable
  559.         mov ds,ax
  560.         lea si,proctable
  561.         les si,[si]
  562.         mov ax,word ptr buffer[2]
  563.         push ax
  564.         mov ax,word ptr buffer
  565.         push ax
  566.         push yo
  567.         push xo
  568.         call dword ptr es:[si+indexputimage*4]
  569.         add sp,8
  570.         pop ds
  571. }
  572. }
  573.  
  574. long imagesize(int x1,int y1,int x2,int y2)
  575. {
  576. asm {
  577.         push ds
  578.         mov ax,SEG proctable
  579.         mov ds,ax
  580.         lea si,proctable
  581.         les si,[si]
  582.         push y2
  583.         push x2
  584.         push y1
  585.         push x1
  586.         call dword ptr es:[si+indeximagesize*4]
  587.         add sp,8
  588.         pop ds
  589. }
  590. }
  591.  
  592. void setglassflag(BYTE glflag) {trflag = glflag;}
  593.  
  594. void closegraph(void)
  595. {
  596. asm {
  597.         mov ah,0
  598.         mov al,oldmode
  599.         int 0x10
  600. }
  601. free(ArrayScanLinesPtr);
  602. }
  603.  
  604. void circle(int x,int y,WORD radius) {ellipse(x,y,radius,radius);}
  605.  
  606. void put4pixels(int xo,int yo,int x,int y)
  607. {
  608.     putpixel(xo+x,yo+y,drawcolor);
  609.     putpixel(xo-x,yo+y,drawcolor);
  610.     putpixel(xo+x,yo-y,drawcolor);
  611.     putpixel(xo-x,yo-y,drawcolor);
  612. }
  613.  
  614. void ellipse(int xo,int yo,WORD xradius,WORD yradius)
  615. {
  616. int x = 0 ,y = yradius;
  617. long a = xradius,b = y;
  618. long asquared = a*a,twoasquared = 2*asquared;
  619. long bsquared = b*b,twobsquared = 2*bsquared;
  620. long d = bsquared - asquared*b + asquared/4;
  621. long dx = 0,dy = twoasquared*b;
  622. while (dx < dy)
  623. {
  624.     put4pixels(xo,yo,x,y);
  625.     if (d > 0)
  626.     {
  627.         y--;
  628.         dy-=twoasquared;
  629.         d-=dy;
  630.     }
  631.     x++;
  632.     dx+=twobsquared;
  633.     d = d+bsquared+dx;
  634. }
  635. d = (3*(asquared-bsquared)/2 -(dx+dy))/2;
  636. while (y >= 0)
  637. {
  638.     put4pixels(xo,yo,x,y);
  639.     if (d < 0)
  640.     {
  641.         x++;
  642.         dx+=twobsquared;
  643.         d+=dx;
  644.     }
  645.     y--;
  646.     dy-=twoasquared;
  647.     d = d-asquared - dy;
  648. }
  649. }
  650.